from httplib import *

class HTTPProxyConnection(HTTPConnection):
    """
    This class provides HTTP access through (authenticated) proxies.
   
    Example:
    If the HTTP proxy address is proxy.your.org:8080, an authenticated proxy
    (one which requires a username/password combination in order to serve
    requests), one can fetch HTTP documents from 'www.webserver.net', port 81:

    conn = HTTPProxyConnection('proxy.your.org:8080', 'www.webserver.net',
        port=81, username='username', password='password')
    conn.connect()
    conn.request("HEAD", "/index.html", headers={'X-Custom-Header-1' : 'Value-1'})
    resp = conn.getresponse()
    ...

    """
    #def __init__(self, proxy, host, port=None, username=None, password=None):
    def __init__(self, host, port=None, proxy=None, username=None, password=None):
        # The connection goes through the proxy
        HTTPConnection.__init__(self, proxy)
        # save the proxy connection settings
        self.__proxy, self.__proxy_port = self.host, self.port
        # self.host and self.port will point to the real host
        self._set_hostport(host, port)
        # save the host and port
        self._host, self._port = self.host, self.port
        # Authenticated proxies support
        self.__username = username
        self.__password = password

    def connect(self):
        """Connect to the host and port specified in __init__ (through a
        proxy)."""
        # We are connecting to the proxy, so use the proxy settings
        self._set_hostport(self.__proxy, self.__proxy_port)
        HTTPConnection.connect(self)
        # Restore the real host and port
        self._set_hostport(self._host, self._port)

    def putrequest(self, method, url):
        """Send a request to the server.

        `method' specifies an HTTP request method, e.g. 'GET'.
        `url' specifies the object being requested, e.g. '/index.html'.
        """
        # The URL has to include the real host
        hostname = self._host
        if self._port != self.default_port:
            hostname = hostname + ':' + str(self._port)
        newurl = "http://%s%s" % (hostname, url)
        # Piggyback on the parent class
        HTTPConnection.putrequest(self, method, newurl)
        # Add proxy-specific headers
        self._add_auth_proxy_header()
       
    def _add_auth_proxy_header(self):
        """Adds an HTTP header for authenticated proxies
        """
        if not self.__username:
            # No username, so assume not an authenticated proxy
            return
        # Authenticated proxy
        import base64
        userpass = "%s:%s" % (self.__username, self.__password)
        #enc_userpass = string.strip(base64.encodestring(userpass))
        enc_userpass = (base64.encodestring(userpass)).strip()
        self.putheader("Proxy-Authorization", "Basic %s" % enc_userpass)
